iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
Modern Web

30天每天寫網站系列 第 4

Day4-自製網站捲軸(中)_想要更多造型

  • 分享至 

  • xImage
  •  

今天開始來寫出自製的捲軸,構想是這樣子的
https://ithelp.ithome.com.tw/upload/images/20210918/20141991p1oER6OqBj.png
根據構想先把框架寫出來

<div class="text_box ">
    <div class="my-scroll">
        <div class="scroll-bar" id="draggable"></div>
    </div>
    <div id="text_content">
        <img src="…" style="width: 100%;">
        ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</br>
        ………
    </div>
</div>

捲軸的部分會分成軌道跟拉桿(會跟著內文動的那個部分),拉桿在軌道內
因為捲軸需要浮在內文上方,所以先把text_content跟my-scroll設定成position: absolute;
並對my-scroll設定right: 0; height: 100%; 讓他置右跟預設捲軸位置重疊
然後拉桿需要在軌道內乖乖待著,所以另外把scroll-bar設定成position: relative;
為了方便觀看這邊先個別設定顏色跟長度,寬度的部分就是自己喜歡就好
設好之後會長這樣
https://ithelp.ithome.com.tw/upload/images/20210918/20141991aPiNt8Tk04.jpg

圖上可以看到我把軌道的寬度設成比拉桿寬,這樣子當軌道顏色拔掉時,就能讓拉桿有上一篇提到的「跟邊框有一些距離」的效果

接下來放入一些內文來讓text_content自己長大
這邊同樣需要對最外框的text_box設定overflow: auto; 或overflow: overlay;
沒設定的話text_content會衝出去外面像這樣
https://ithelp.ithome.com.tw/upload/images/20210918/20141991vOi6P7dgf0.jpg
再來就是因為我們雖然會自己做出假的捲軸,卻沒辦法做出捲動的效果,所以還是需要使用到CSS本身捲軸的捲動功能
設定好overflow後,會發現我們自製的捲軸被CSS做出來的捲軸擋住
https://ithelp.ithome.com.tw/upload/images/20210918/201419910R0F0DPCQJ.jpg
所以我們需要把CSS的捲軸隱藏起來
這邊我們要利用上一篇有使用到的chrome捲軸語法
直接把預設捲軸顏色設成透明的

.text_box::-webkit-scrollbar {
    background: transparent;
}

就會發現我們成功把捲軸隱藏了,但依舊保有捲軸的功能在
https://i.imgur.com/QhXoWQe.gif
同時也會發現,因為原本的捲軸比較寬,所以會發生沒點在捲軸上,內文卻可以移動的狀況,這時候我們就要依據我們自製捲軸的寬度,去讓預設捲軸的寬度與自製的捲軸完全相符
這邊我的my-scroll是設定width: 7px; 為了點擊比較好點,預設捲軸就設定成9px

.text_box::-webkit-scrollbar {
    width: 9px;
    background: transparent;
}

CSS的部分就到這邊,接下來我們要進入JS了
前一張動圖中應該有發現,雖然我們預設的捲軸有在作用,但我們的漂亮捲軸一捲就跟著內文跑上去了
這是因為my-scroll的預設top: 0; 如果父層text_box捲軸捲動,text_box的內容就會被往上捲,「0」的位置也會被拉上去,像是圖片這樣
https://ithelp.ithome.com.tw/upload/images/20210918/20141991dALVaOet3G.png
所以我們需要讓my-scroll的top自己改變數值,這個就要在JS中抓取東西給my-scroll使用了

首先我們要有一個概念
如果要讓my-scroll一直存在我們的視線中,它的top值就必須跟我們捲軸捲動的量是一樣的,往下卷就增加,往上捲就減少
這裡要用到.scrollTop()這個函數,它的作用是可以偵測目前捲動的位置距離頂層多少數值
而我們需要在「捲動當下」不斷地偵測然後把數字給my-scroll,所以要這樣子寫

$('.text_box').scroll(function () {
    $('.my-scroll').attr("style", "top:" +$(this).scrollTop() + "px");
})

因為.scrollTop()給的只有數值,但top需要有px,所以我們要自己補充px給它,然後我們的my-scroll就會像是停在原地一樣不動了
https://i.imgur.com/7bgrQNr.gif

接下來是需要思考的地方
我們無法每一次都幫內文卡好一個死死的數字,然後手動都去計算「拉桿」需要多長
所以我們要讓JS去幫我們計算並設定我們的拉桿長度,這邊先把為了方便截圖而設定好的scroll-bar高度拿掉
https://ithelp.ithome.com.tw/upload/images/20210918/20141991M2r9oCXodn.jpg

然後看看這張圖
https://ithelp.ithome.com.tw/upload/images/20210918/20141991nXjfiCpcIw.png
從圖上我們看出
整體長度 : 可視長度 = 捲軸長度 : 拉桿長度
根據數學計算可以得出
拉桿長度 = 可視長度 * 捲軸長度 / 整體長度
知道算法後我們在JS中寫入

var scroll_h = $('.text_box').height() * $('.my-scroll').height() / $('#text_content').height();
$('.scroll-bar').attr("style", "height:" + scroll_h + "px");

利用JS去計算拉桿長度後,就不用擔心內文有增減而必須去改其他拉桿相關的數值了!!
https://ithelp.ithome.com.tw/upload/images/20210918/20141991z7aAjNDwl1.jpg

接著我們要讓自製的拉桿也能像捲軸一樣捲動
剛剛我們已經知道要怎麼去獲得捲動的數值,但因為我們的拉桿移動的範圍只在my-scroll之中,所以原本捲動的數值我們也要按比例做縮小
換算完再給拉桿做使用,整體的JS程式碼是這樣

/*--自製假滾輪--*/
    var scroll_h = $('.text_box').height() * $('.my-scroll').height() / $('#text_content').height();
    $('.scroll-bar').attr("style", "height:" + scroll_h + "px");
    var scroll_ = 0;  //滾動多少
    var scroll_float = 0;
    var scale_ = $('#text_content').height() / $('.text_box').height() //可視範圍占整體比例
    $('.text_box').scroll(function () {
        scroll_ = $(this).scrollTop()
        scroll_float = scroll_ / scale_ //總滾動大小轉換成可視範圍比例大小
        $('.my-scroll').attr("style", "top:" + $(this).scrollTop() + "px");
        $('.scroll-bar').attr("style", "top:" + scroll_float + "px;height:" + scroll_h + "px");
    })

這樣就完成自製假滾輪的樣子啦!!
https://i.imgur.com/pepkxVi.gif

然後我們就可以利用改變div的z-index數值,做出平時在圖片下面,hover時在圖片上面的效果了
把辣眼睛的顏色都拿掉後就完成啦!!
https://i.imgur.com/a6pA1Oe.gif
也能在hover時讓拉桿出現不同顏色或透明度之類的!!

明天寫這個系列最後一篇,如果我就特立獨行想把拉桿放左邊或中間那該怎麼做呢?


上一篇
Day3-自製網站捲軸(上)_CSS就能做得到
下一篇
Day5-自製網站捲軸(下)_我就特立獨行
系列文
30天每天寫網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言